#pragma once

#include <windows.h>

#include <boost/thread/tss.hpp>


namespace platform {

class ThreadMemoryAllocator
{
private:
	static inline HANDLE getThreadHandle(void) {
		HANDLE *pH = ms_tls.get();
		if (pH == NULL || *pH == NULL) {
			// first allocation from this thread
			pH = new HANDLE;
			*pH = ::HeapCreate(HEAP_NO_SERIALIZE, 0, 0);
			ms_tls.reset(pH);
		}
		return *pH;
	}

public:
	ThreadMemoryAllocator(void);
	virtual ~ThreadMemoryAllocator(void);

	static inline void * Allocate(SIZE_T size) {
		return ::HeapAlloc(getThreadHandle(), HEAP_NO_SERIALIZE, size);
	}

	static inline void Free(void *p) {
		::HeapFree(getThreadHandle(), HEAP_NO_SERIALIZE, p);
	}

private:
	static void OnTreadExit(HANDLE *ph) {
		if (ph != NULL && *ph != NULL)
			::HeapDestroy(*ph);
	}

	static boost::thread_specific_ptr<HANDLE> ms_tls;
};


}  // end namespace